package com.fangdd.logtrace.http;

import com.fangdd.logtrace.BoundsLog;
import com.fangdd.logtrace.TraceId;
import com.fangdd.logtrace.TraceIdThreadLocal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;

import java.io.IOException;

/**
 * Created by sulong on 16-9-8.
 */
public class TraceIdRestTemplateInterceptor implements ClientHttpRequestInterceptor {
    private static final Logger LOGGER = LoggerFactory.getLogger(TraceIdRestTemplateInterceptor.class);

    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        TraceId next = TraceIdThreadLocal.sequentialNext();
        String method = "http:" + request.getMethod().name() + ":" + request.getURI();
        if (!next.isUnset()) {
            request.getHeaders().add(TraceIdHttpFilter.TRACE_ID_HEADER_NAME, next.toString());
            BoundsLog.callerIn(LOGGER, next.toString(), method);
        }

        long startTime = System.currentTimeMillis();
        try {
            ClientHttpResponse response = execution.execute(request, body);
            if (!next.isUnset()) {
                BoundsLog.callerOut(LOGGER, next.toString(), method, true, System.currentTimeMillis() - startTime);
            }
            return response;
        } catch (IOException e) {
            LOGGER.error("", e);
            if (!next.isUnset()) {
                BoundsLog.callerOut(LOGGER, next.toString(), method, false, System.currentTimeMillis() - startTime);
            }
            throw e;
        }
    }
}
